---
title: 数据获取
description: 学习如何使用 Astro fetch API 获取远程数据。
---
`.astro` 文件可以在构建时获取远程数据来辅助页面生成。


## Astro 中的 `fetch()`

所有 [Astro 组件](/zh-cn/basics/astro-components/) 都可以在它们的组件脚本中通过[全局 `fetch()` 函数](https://developer.mozilla.org/zh-CN/docs/Web/API/fetch)来使用完整的 URL（例如 `https://example.com/api` ）发起 HTTP 请求到 API。
此外，你可以使用 [`new URL("/api", Astro.url)`](/zh-cn/reference/api-reference/#url) 构建一个 URL，指向你的项目中按需在服务器上渲染的页面和端点。

fetch 调用将会在构建时执行，并且数据都可用于组件模板中来生成动态 HTML。如果启用 [SSR](/zh-cn/guides/on-demand-rendering/) 模式，任何 fetch 调用都将在运行时执行。

💡 在 Astro 组件 script 中使用 [**顶层 `await`**](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await#top_level_await) 的优势。

💡 将获取的数据作为参数传递给 Astro 和框架组件。

```astro /await fetch\\(.*?\\);/
---
// src/components/User.astro
import Contact from "../components/Contact.jsx";
import Location from "../components/Location.astro";

const response = await fetch("https://randomuser.me/api/");
const data = await response.json();
const randomUser = data.results[0]
---
<!-- 获取的数据可以在构建时在 HTML 中渲染 -->
<h1>User</h1>
<h2>{randomUser.name.first} {randomUser.name.last}</h2>

<!-- 获取的数据可以在构建时传递给组件作为参数 -->
<Contact client:load email={randomUser.email} />
<Location city={randomUser.location.city} />
```

:::note
请记住，Astro 组件中的所有数据都是在渲染组件时获取的。

你部署的 Astro 站点将在**构建时获取一次数据**。在开发中，你将在组件刷新时看到数据获取。如果你需要在客户端多次重新获取数据，请在 Astro 组件中使用[框架组件](/zh-cn/guides/framework-components/)或[客户端脚本](/zh-cn/guides/client-side-scripts/)。
:::

## 在框架组件中使用 `fetch()`

`fetch()` 函数也可在任何[框架组件](/zh-cn/guides/framework-components/)中全局使用：

```tsx title="src/components/Movies.tsx" /await fetch\\(.*?\\)/
import type { FunctionalComponent } from 'preact';

const data = await fetch('https://example.com/movies.json').then((response) => response.json());

// 构建时渲染的组件也会输出日志到 CLI。
// 当用 `client:*` 指令渲染时，它们也会输出到浏览器控制台。
console.log(data);

const Movies: FunctionalComponent = () => {
  // 将结果输出到页面上
  return <div>{JSON.stringify(data)}</div>;
};

export default Movies;
```

## GraphQL 查询

Astro 也可以使用 `fetch()` 和任一有效的 GraphQL 查询来查询 GraphQL 服务器。

```astro title="src/components/Film.astro" "await fetch"
---
const response = await fetch(
  "https://swapi-graphql.netlify.app/.netlify/functions/index",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },    body: JSON.stringify({
      query: `
        query getFilm ($id:ID!) {
          film(id: $id) {
            title
            releaseDate
          }
        }
      `,
      variables: {
        id: "ZmlsbXM6MQ==",
      },
    }),
  }
);

const json = await response.json();
const { film } = json.data;
---
<h1>获取有关《星球大战：曙光乍现》的信息</h1>
<h2>标题：{film.title}</h2>
<p>年份：{film.releaseDate}</p>
```

## 从无头 CMS 中获取

Astro 组件可以从你最喜欢的 CMS 中获取数据，然后将其呈现为页面内容。使用[动态路由](/zh-cn/guides/routing/#动态路由)，组件甚至可以根据你的 CMS 内容生成页面。

请参阅 [CMS 指南](/zh-cn/guides/cms/)，查看有关将 Astro 与无头 CMS（包括 Storyblok、Contentful 和 WordPress）集成的完整详细信息。


## 社区资源

- [使用 Astro 和 GraphQL 构建一个全栈 App](https://robkendal.co.uk/blog/how-to-build-astro-site-with-graphql/)
